﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;

namespace HML
{
    /// <summary>
    /// 滑块
    /// </summary>
    [TypeConverter(typeof(PropertyOrderConverter))]
    public class MultidropSlideLump
    {
        #region 属性

        private string key = "";
        /// <summary>
        /// 滑块Key（必须唯一，可用于索引）
        /// </summary>
        [Description("滑块Key（必须唯一，可用于索引）")]
        [Category("杂项_滑块")]
        [PropertyOrder(-200)]
        [DefaultValue("")]
        public string Key
        {
            get { return this.key; }
            set
            {
                if (this.key == value)
                    return;

                this.key = value;
            }
        }

        private string title = "";
        /// <summary>
        /// 滑块标题
        /// </summary>
        [Description("滑块标题")]
        [Category("杂项_滑块")]
        [PropertyOrder(-199)]
        [DefaultValue("")]
        public string Title
        {
            get { return this.title; }
            set
            {
                if (this.title == value)
                    return;

                this.title = value;
                if (this.owner != null)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private double selfValue = 0;
        /// <summary>
        /// 滑块值（只修改自己值和触发自己事件，不影响其他滑块值）
        /// </summary>
        [Description("修改滑块值（只修改自己值和触发自己事件，不影响其他滑块值）")]
        [Category("杂项_滑块")]
        [PropertyOrder(-198)]
        [DefaultValue(0D)]
        public double SelfValue
        {
            get { return this.selfValue; }
            set
            {
                if (this.selfValue == value)
                    return;

                if (this.owner == null)
                {
                    this.selfValue = value;
                }
                else
                {
                    this.ChangeSelfValue(value, true);
                }
            }
        }

        /// <summary>
        /// 滑块值（修改自己值和触发自己事件，同时影响其他滑块值，直到遇到已锁滑块才终止影响）
        /// </summary>
        [Description("修改滑块值（修改自己值和触发自己事件，同时影响其他滑块值，直到遇到已锁滑块才终止影响）")]
        [Category("杂项_滑块")]
        [Browsable(false)]
        [PropertyOrder(-196)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public double InfluencedValue
        {
            get { return this.selfValue; }
            set
            {
                if (this.selfValue == value)
                    return;

                if (this.owner == null)
                {
                    this.selfValue = value;
                }
                else
                {
                    this.ChangeInfluencedValue(value, true);
                }
            }
        }

        private Color lumpActivateColor = Color.Empty;
        /// <summary>
        /// 滑块激活的虚线框颜色（空值通用通用配置）
        /// </summary>
        [Description("滑块激活的虚线框颜色（空值通用通用配置）")]
        [Category("杂项_滑块")]
        [PropertyOrder(-194)]
        [DefaultValue(typeof(Color), "")]
        public Color LumpActivateColor
        {
            get { return this.lumpActivateColor; }
            set
            {
                if (this.lumpActivateColor == value)
                    return;

                this.lumpActivateColor = value;
                if (this.owner != null)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private Color lumpBorderColor = Color.Empty;
        /// <summary>
        /// 滑块边框颜色（空值通用通用配置）
        /// </summary>
        [Description("滑块边框颜色（空值通用通用配置）")]
        [Category("杂项_滑块")]
        [PropertyOrder(-193)]
        [DefaultValue(typeof(Color), "")]
        public Color LumpBorderColor
        {
            get { return this.lumpBorderColor; }
            set
            {
                if (this.lumpBorderColor == value)
                    return;

                this.lumpBorderColor = value;
                if (this.owner != null)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private Color lumpBackColor = Color.Empty;
        /// <summary>
        /// 滑块颜色（空值通用通用配置）
        /// </summary>
        [Description("滑块颜色（空值通用通用配置）")]
        [Category("杂项_滑块")]
        [PropertyOrder(-192)]
        [DefaultValue(typeof(Color), "")]
        public Color LumpBackColor
        {
            get { return this.lumpBackColor; }
            set
            {
                if (this.lumpBackColor == value)
                    return;

                this.lumpBackColor = value;
                if (this.owner != null)
                {
                    this.owner.Invalidate();
                }
            }
        }



        private bool lumpLocked = false;
        /// <summary>
        /// 滑块是否已锁定
        /// </summary>
        [Description("滑块是否已锁定")]
        [Category("杂项_滑块锁")]
        [PropertyOrder(-180)]
        [DefaultValue(false)]
        public bool LumpLocked
        {
            get { return this.lumpLocked; }
            set
            {
                if (this.lumpLocked == value)
                    return;

                this.lumpLocked = value;
                if (this.owner != null)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private Color lumpLockColor = Color.Empty;
        /// <summary>
        /// 滑块锁颜色（空值通用通用配置）
        /// </summary>
        [Description(" 滑块锁颜色（空值通用通用配置）")]
        [Category("杂项_滑块锁")]
        [PropertyOrder(-178)]
        [DefaultValue(typeof(Color), "")]
        public Color LumpLockColor
        {
            get { return this.lumpLockColor; }
            set
            {
                if (this.lumpLockColor == value)
                    return;

                this.lumpLockColor = value;
                if (this.owner != null)
                {
                    this.owner.Invalidate();
                }
            }
        }



        private Color tipTitleBackColor = Color.Empty;
        /// <summary>
        /// 提示标题背景颜色（空值通用通用配置）
        /// </summary>
        [Description("提示标题背景颜色（空值通用通用配置）")]
        [Category("杂项_提示标题")]
        [PropertyOrder(-126)]
        [DefaultValue(typeof(Color), "")]
        public Color TipTitleBackColor
        {
            get { return this.tipTitleBackColor; }
            set
            {
                if (this.tipTitleBackColor == value)
                    return;

                this.tipTitleBackColor = value;
                if (this.owner != null && this.owner.TipTitleVisible)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private Color tipTitleForeColor = Color.Empty;
        /// <summary>
        /// 提示标题文本颜色（空值通用通用配置）
        /// </summary>
        [Description("提示标题文本颜色（空值通用通用配置）")]
        [Category("杂项_提示标题")]
        [PropertyOrder(-124)]
        [DefaultValue(typeof(Color), "")]
        public Color TipTitleForeColor
        {
            get { return this.tipTitleForeColor; }
            set
            {
                if (this.tipTitleForeColor == value)
                    return;

                this.tipTitleForeColor = value;
                if (this.owner != null && this.owner.TipTitleVisible)
                {
                    this.owner.Invalidate();
                }
            }
        }



        private Color tipValueBackColor = Color.Empty;
        /// <summary>
        /// 提示值背景颜色（空值通用通用配置）
        /// </summary>
        [Description(" 提示值背景颜色（空值通用通用配置）")]
        [Category("杂项_提示值")]
        [PropertyOrder(-160)]
        [DefaultValue(typeof(Color), "")]
        public Color TipValueBackColor
        {
            get { return this.tipValueBackColor; }
            set
            {
                if (this.tipValueBackColor == value)
                    return;

                this.tipValueBackColor = value;
                if (this.owner != null && this.owner.TipValueVisible)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private Color tipValueForeColor = Color.Empty;
        /// <summary>
        /// 提示值文本颜色（空值通用通用配置）
        /// </summary>
        [Description(" 提示值文本颜色（空值通用通用配置）")]
        [Category("杂项_提示值")]
        [PropertyOrder(-158)]
        [DefaultValue(typeof(Color), "")]
        public Color TipValueForeColor
        {
            get { return this.tipValueForeColor; }
            set
            {
                if (this.tipValueForeColor == value)
                    return;

                this.tipValueForeColor = value;
                if (this.owner != null && this.owner.TipValueVisible)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private MultidropSlide owner = null;
        /// <summary>
        /// 选项所属的控件
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public MultidropSlide Owner
        {
            get { return this.owner; }
            internal protected set { this.owner = value; }
        }

        #region 临时存储

        /// <summary>
        /// 滑块rect
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal RectangleF LumpRect { get; set; }

        /// <summary>
        /// 滑块开始坐标(滑块中心为参考点)
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal float Lump_Start_Point { get; set; }

        /// <summary>
        /// 滑块结束坐标(滑块中心为参考点)
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal float Lump_End_Point { get; set; }



        /// <summary>
        /// 提示标题rect
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal Rectangle TipTitleRect { get; set; }

        /// <summary>
        /// 提示标题连线的开始坐标
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal PointF TipTitleStartPoint { get; set; }

        /// <summary>
        /// 提示标题连线的结束坐标
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal PointF TipTitleEndPoint { get; set; }



        /// <summary>
        /// 提示值rect
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal Rectangle TipValueRect { get; set; }

        /// <summary>
        /// 提示值连线的开始坐标
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal PointF TipValueStartPoint { get; set; }

        /// <summary>
        /// 提示值连线的结束坐标
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal PointF TipValueEndPoint { get; set; }

        #endregion

        #endregion

        #region 公开方法

        /// <summary>
        /// 修改滑块值，但不会触发任何事情
        /// </summary>
        /// <param name="value"></param>
        internal void OnlySetValue(double value)
        {
            this.selfValue = value;
        }

        /// <summary>
        /// 修改滑块值（只修改自己值和触发自己事件，不影响其他滑块值）
        /// </summary>
        /// <param name="value">要修改的滑块值</param>
        /// <param name="ignoreLocked">是否忽略自己的滑块锁</param>
        /// <returns></returns>
        internal bool ChangeSelfValue(double value, bool ignoreLocked)
        {
            if (this.owner == null || (ignoreLocked == false && this.LumpLocked))
            {
                return false;
            }
            if (this.selfValue == value)
            {
                return false;
            }

            value = Math.Max(value, this.owner.MinValue);
            value = Math.Min(value, this.owner.MaxValue);
            if (this.owner.Items.Count > 1)
            {
                int current_lump_index = this.owner.Items.IndexOf(this);
                // 防止小于左边滑块值
                if (current_lump_index > 0)
                {
                    value = Math.Max(value, this.owner.Items[current_lump_index - 1].SelfValue);
                }
                // 防止大于右边滑块值
                if (current_lump_index < this.owner.Items.Count - 1)
                {
                    value = Math.Min(value, this.owner.Items[current_lump_index + 1].SelfValue);
                }
            }
            if (this.selfValue == value)
            {
                return false;
            }

            this.selfValue = value;
            this.owner.InitializeLumpRectangle(this);
            this.owner.OnValueChanged(new MultidropSlideValueChangedEventArgs(this, this, null));
            this.owner.Invalidate();

            return true;
        }

        /// <summary>
        /// 修改滑块值（修改自己值和触发自己事件，同时影响其他滑块值，直到遇到已锁滑块才终止影响）
        /// </summary>
        /// <param name="value">要修改的滑块值</param>
        /// <param name="ignoreLocked">是否忽略自己的滑块锁</param>
        /// <returns></returns>
        internal bool ChangeInfluencedValue(double value, bool ignoreLocked)
        {
            if (this.owner == null || (ignoreLocked == false && this.LumpLocked))
            {
                return false;
            }

            value = Math.Max(value, this.owner.MinValue);
            value = Math.Min(value, this.owner.MaxValue);
            if (this.selfValue == value)
            {
                return false;
            }

            double selfvalue_tmp = value;
            List<MultidropSlideLump> influencedLumps = new List<MultidropSlideLump>();

            if (this.owner.Items.Count > 1)
            {
                int current_lump_index = this.owner.Items.IndexOf(this);

                // 防止小于左边禁止滑块值
                if (value < this.selfValue)
                {
                    for (int i = current_lump_index - 1; i >= 0; i--)
                    {
                        if (this.owner.Items[i].SelfValue > value)
                        {
                            if (this.owner.Items[i].LumpLocked)
                            {
                                selfvalue_tmp = this.owner.Items[i].SelfValue;
                                break;
                            }
                            else
                            {
                                influencedLumps.Add(this.owner.Items[i]);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                // 防止大于右边禁止滑块值
                else if (value > this.selfValue)
                {
                    for (int i = current_lump_index + 1; i < this.owner.Items.Count; i++)
                    {
                        if (this.owner.Items[i].SelfValue < value)
                        {
                            if (this.owner.Items[i].LumpLocked)
                            {
                                selfvalue_tmp = this.owner.Items[i].SelfValue;
                                break;
                            }
                            else
                            {
                                influencedLumps.Add(this.owner.Items[i]);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }


                if (this.selfValue == selfvalue_tmp)
                {
                    return false;
                }
                for (int i = influencedLumps.Count - 1; i >= 0; i--)
                {
                    influencedLumps[i].selfValue = selfvalue_tmp;
                    this.owner.InitializeLumpRectangle(influencedLumps[i]);
                    this.owner.OnValueChanged(new MultidropSlideValueChangedEventArgs(this.owner.Items[current_lump_index], influencedLumps[i], influencedLumps));
                }
            }

            this.selfValue = selfvalue_tmp;
            this.owner.InitializeLumpRectangle(this);
            this.owner.OnValueChanged(new MultidropSlideValueChangedEventArgs(this, this, influencedLumps.Count < 1 ? null : influencedLumps));
            this.owner.Invalidate();

            return true;
        }

        /// <summary>
        /// 复制滑块
        /// </summary>
        /// <returns></returns>
        public virtual MultidropSlideLump Copy()
        {
            MultidropSlideLump lump = new MultidropSlideLump()
            {
                Key = this.Key,
                Title = this.Title,
                SelfValue = this.SelfValue,
                LumpActivateColor = this.LumpActivateColor,
                LumpBorderColor = this.LumpBorderColor,
                LumpBackColor = this.LumpBackColor,
                LumpLocked = this.LumpLocked,
                LumpLockColor = this.LumpLockColor,
                TipTitleBackColor = this.TipTitleBackColor,
                TipTitleForeColor = this.TipTitleForeColor,
                TipValueBackColor = this.TipValueBackColor,
                TipValueForeColor = this.TipValueForeColor,
            };

            return lump;
        }

        #endregion

    }

}
